using System.Text;
using AnQinFrameWorkAPI.Common.Mapper;
using AnQinFrameWorkAPI.DataBase;
using AnQinFrameWorkAPI.Service.BaseInfo;
using AnQinFrameWorkAPI.Service.Blog;
using AnQinFrameWorkAPI.Service.Develop;
using AnQinFrameWorkAPI.Service.SystemCore;
using FrameWork.Config;
using FrameWork.JWT;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using static System.Net.Mime.MediaTypeNames;

namespace AnQinFrameWorkAPI;

public class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);

        #region 转换Json

        builder.Services.AddControllers().AddJsonOptions(options =>
        {
            //时间
            options.JsonSerializerOptions.Converters.Add(new DateTimeConverter());
        });

        #endregion

        #region JWT校验

        //增加校验
        var jwtSection = builder.Configuration.GetSection("Jwt");
        var key = jwtSection.GetValue<string>("Key");
        var issuer = jwtSection.GetValue<string>("Issuer");
        var audience = jwtSection.GetValue<string>("Audience");

        //校验方法
        builder.Services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        }).AddJwtBearer(options =>
        {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateLifetime = true,
                ValidateIssuerSigningKey = true,
                ValidIssuer = issuer,
                ValidAudience = audience,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key))
            };
        });
        //增加校验服务
        builder.Services.AddScoped<TokenService>();
        builder.Services.AddAuthorization();

        #endregion

        #region 增加控制器API，校验字段模型必填

        builder.Services.AddControllers().ConfigureApiBehaviorOptions(options =>
        {
            options.InvalidModelStateResponseFactory = context =>
            {
                var entry = context.ModelState.Values
                    .Where(a => a.ValidationState == ModelValidationState.Invalid).FirstOrDefault();
                return new BadRequestObjectResult(context.ModelState)
                {
                    ContentTypes =
                    {
                        Application.Json
                    },
                    Value = new
                    {
                        Message = entry?.Errors.FirstOrDefault()?.ErrorMessage,
                        Status = 400
                    }
                };
            };
        });

        #endregion

        #region 跨域

        builder.Services.AddCors(options =>
        {
            options.AddPolicy("AllowSpecificOrigins",
                policyBuilder => policyBuilder
                    .AllowAnyOrigin()
                    .AllowAnyMethod()
                    .AllowAnyHeader()
            );
        });

        #endregion

        #region mapper

        builder.Services.AddAutoMapper(
            typeof(SystemCoreMapper).Assembly,
            typeof(BlogMapper).Assembly,
            typeof(DevelopMapper).Assembly,
            typeof(BaseInfoMapper).Assembly);

        #endregion

        #region 数据库链接

        builder.Services.AddDbContext<DatabaseContext>(options =>
            options.UseSqlServer(
                builder.Configuration.GetConnectionString("DefaultConnection")
            )
        );

        #endregion

        #region 增加业务层

        #region 系统

        builder.Services.AddScoped<LoginService>();
        builder.Services.AddScoped<MenuService>();
        builder.Services.AddScoped<MenuButtonService>();
        builder.Services.AddScoped<MenuFieldService>();
        builder.Services.AddScoped<RoleService>();
        builder.Services.AddScoped<CodeRuleService>();
        builder.Services.AddScoped<SystemConfigService>();
        builder.Services.AddScoped<UpLoadService>();
        builder.Services.AddScoped<RoleMenuService>();
        builder.Services.AddScoped<RoleButtonService>();
        builder.Services.AddScoped<RoleFieldService>();

        #endregion

        #region 基础

        builder.Services.AddScoped<StaffService>();
        builder.Services.AddScoped<DepartmentService>();

        #endregion

        #region 博客

        builder.Services.AddScoped<BlogCommentService>();
        builder.Services.AddScoped<BlogDevelopHistoryService>();
        builder.Services.AddScoped<BlogGlobalConfigService>();
        builder.Services.AddScoped<BlogMenuService>();
        builder.Services.AddScoped<BlogProjectCaseService>();
        builder.Services.AddScoped<BlogTeamMemberService>();
        builder.Services.AddScoped<BlogTextService>();
        builder.Services.AddScoped<BlogUserService>();
        builder.Services.AddScoped<BlogLoginService>();

        #endregion

        #region 研发

        builder.Services.AddScoped<DevelopProjectCustomerService>();
        builder.Services.AddScoped<DevelopProjectListService>();
        builder.Services.AddScoped<DevelopProjectDemandService>();
        builder.Services.AddScoped<DevelopProjectSaleService>();
        builder.Services.AddScoped<DevelopProjectDevelopmentService>();
        builder.Services.AddScoped<DevelopProjectImplementService>();

        #endregion

        #endregion

        builder.Services.AddEndpointsApiExplorer();

        #region 增加解密token

        builder.Services.AddHttpContextAccessor();
        builder.Services.AddScoped<IUserContext, HttpUserContext>();

        #endregion

        #region 配置swagger

        builder.Services.AddSwaggerGen(option =>
        {
            //分块
            option.SwaggerDoc("SystemCore", new OpenApiInfo
            {
                Title = "安沁后台管理系统框架",
                Version = "v1",
                Description = "系统"
            });
            option.SwaggerDoc("BaseInfo", new OpenApiInfo
            {
                Title = "安沁后台管理系统框架",
                Version = "v1",
                Description = "基础"
            });
            option.SwaggerDoc("Blog", new OpenApiInfo
            {
                Title = "安沁后台管理系统框架",
                Version = "v1",
                Description = "博客"
            });
            option.SwaggerDoc("Develop", new OpenApiInfo
            {
                Title = "安沁后台管理系统框架",
                Version = "v1",
                Description = "研发"
            });
            var fileList = new[]
            {
                "AnQinFrameWorkAPI.xml"
            };
            //读取xml
            foreach (var item in fileList)
            {
                var file = Path.Combine(AppContext.BaseDirectory, item);
                var path = Path.Combine(AppContext.BaseDirectory, file);
                option.IncludeXmlComments(path, true);
            }

            option.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
            {
                Description = "JWT授权格式: Bearer {你的Token}",
                Name = "Authorization",
                In = ParameterLocation.Header,
                Type = SecuritySchemeType.ApiKey,
                Scheme = "Bearer",
                BearerFormat = "JWT"
            });
            option.AddSecurityRequirement(new OpenApiSecurityRequirement
            {
                {
                    new OpenApiSecurityScheme
                    {
                        Reference = new OpenApiReference
                        {
                            Type = ReferenceType.SecurityScheme,
                            Id = "Bearer"
                        }
                    },
                    Array.Empty<string>()
                }
            });
        });

        #endregion

        var app = builder.Build();

        app.UseCors("AllowSpecificOrigins");

        app.UseSwagger();
        app.UseSwaggerUI(c =>
        {
            c.SwaggerEndpoint("/swagger/SystemCore/swagger.json", "SystemCore");
            c.SwaggerEndpoint("/swagger/BaseInfo/swagger.json", "BaseInfo");
            c.SwaggerEndpoint("/swagger/Blog/swagger.json", "Blog");
            c.SwaggerEndpoint("/swagger/Develop/swagger.json", "Develop");
        });

        app.UseAuthentication();
        app.UseAuthorization();

        app.MapControllers();
        app.UseDefaultFiles(new DefaultFilesOptions
        {
            DefaultFileNames = new[] { "index.html" }
        });

        app.UseStaticFiles();

        app.Run();
    }
}